package coe.pumbaa

import org.springframework.dao.DataIntegrityViolationException
import grails.plugins.springsecurity.Secured

class PostController {

    static allowedMethods = [save: "POST", update: "POST"]

    def stringManagerService
    def springSecurityService
    def authenticationManagerService
    
    def index() {
        redirect(controller: 'home',action: "index")
    }

    def list() {
        def user
        if(springSecurityService.isLoggedIn()){
         user = springSecurityService.currentUser
        }else{
         user = authenticationManagerService.getAnonymousUser()
        }
        def category = Category.get(params.id)

        if(stringManagerService.checkObjectInString(user.role,category.allowView)){
            params.max = Math.min(params.max ? params.int('max') : 10, 100)
            def posts = Post.findAll("from Post as p where p.category=? order by timestamp DESC",[category],params)
            [roleUser:user.role,postInstanceList: posts, postInstanceTotal: Post.findAll("from Post as p where p.category=? order by timestamp DESC",[category]).size(),catInstance:category,postInstance: new Post(), navigation:[pos:"post", params:["categoryID":category.id]]]
        }else{
            flash.warning = "You can not view category ("+category.title+")."
            redirect(controller:'home',action:'index')
        }
    }

    def save() {
        def user
        if(springSecurityService.isLoggedIn()){
         user = springSecurityService.currentUser
        }else{
         user = authenticationManagerService.getAnonymousUser()
        }
        def category = Category.get(params.catID)
        if(stringManagerService.checkObjectInString(user.role,category.allowPost)){
            def postInstance = new Post(params)
            postInstance.timestamp = new Date()
            postInstance.category = category
            postInstance.owner = user
            if (!postInstance.save(flush: true)) {
                flash.error = "Error! Can not create post plese check your input."
            }else{
                flash.success = message(code: 'default.created.message', args: [message(code: 'post.label', default: 'Post'), postInstance.id])
            }
            redirect(action: "list", id: params.catID)
        }else{
            flash.warning = "You can not post in category ("+category.title+")."
            redirect(controller:'home',action:'index')
        }
    }

    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def edit() {
        if(springSecurityService.currentUser.role.level <= 1){
            def postInstance = Post.get(params.id)
            if (!postInstance) {
                flash.error = message(code: 'default.not.found.message', args: [message(code: 'post.label', default: 'Post'), params.id])
                redirect(action: "list")
                return
            }

            [postInstance: postInstance]
        }else{
            flash.warning = "You are not admin or staff."
            redirect(controller:'home',action:'index')
        }
    }

    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def update() {
        if(springSecurityService.currentUser.role.level <= 1){
            def postInstance = Post.get(params.id)
            if (!postInstance) {
                flash.error = message(code: 'default.not.found.message', args: [message(code: 'post.label', default: 'Post'), params.id])
                redirect(action: "list",id:params.catID)
                return
            }

            if (params.version) {
                def version = params.version.toLong()
                if (postInstance.version > version) {
                    postInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                        [message(code: 'post.label', default: 'Post')] as Object[],
                          "Another user has updated this Post while you were editing")
                    render(view: "edit", model: [postInstance: postInstance])
                    return
                }
            }

            postInstance.properties = params

            if (!postInstance.save(flush: true)) {
                render(view: "edit", model: [postInstance: postInstance])
                return
            }

            flash.success = message(code: 'default.updated.message', args: [message(code: 'post.label', default: 'Post'), postInstance.id])
            redirect(action: "list",id:params.catID)
        }else{
            flash.warning = "You are not admin or staff."
            redirect(controller:'home',action:'index')
        }
    }

    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def delete() {
        if(springSecurityService.currentUser.role.level <= 1){
            def postInstance = Post.get(params.id)
            def catID = postInstance.category.id

            try {
                postInstance.delete(flush: true)
                flash.success = message(code: 'default.deleted.message', args: [message(code: 'post.label', default: 'Post'), params.id])
                redirect(action: "list",id:catID)
            }
            catch (DataIntegrityViolationException e) {
                flash.error = message(code: 'default.not.deleted.message', args: [message(code: 'post.label', default: 'Post'), params.id])
                redirect(action: "list",id:catID)
            }
        }else{
            flash.warning = "You are not admin or staff."
            redirect(controller:'home',action:'index')
        }
    }
    
    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def like(){
        def user = springSecurityService.currentUser
        def post = Post.get(params.id)
        if(stringManagerService.checkObjectInString(user.role,post.category.allowView)){
            post.likes = stringManagerService.addObjectInToString(springSecurityService?.currentUser,post.likes)
            post.save(flush:true)
            render(template: 'like' , model:[postInstance:post])
        }else{
            flash.warning = "You can not view category ("+category.title+")."
            redirect(controller:'home',action:'index')
        }
    }
    
    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def dislike(){
        def user = springSecurityService.currentUser
        def post = Post.get(params.id)
        if(stringManagerService.checkObjectInString(user.role,post.category.allowView)){
            post.likes = stringManagerService.deleteObjectFromString(springSecurityService?.currentUser,post.likes)
            post.save(flush:true)
            render(template: 'like' , model:[postInstance:post])
        }else{
            flash.warning = "You can not view category ("+category.title+")."
            redirect(controller:'home',action:'index')
        }
    }
    
    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def subscribe(){
        def user = springSecurityService.currentUser
        def post = Post.get(params.id)
        if(stringManagerService.checkObjectInString(user.role,post.category.allowView)){
            user.subscribe = stringManagerService.addObjectInToString(post,user.subscribe)
            user.save(flush:true)
            render(template: 'subscribe' ,model: [postInstance:post])
        }else{
            flash.warning = "You can not view category ("+category.title+")."
            redirect(controller:'home',action:'index')
        }
    }
    
    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
    def unSubscribe(){
        def user = springSecurityService.currentUser
        def post = Post.get(params.id)
        println "#" + user.subscribe
        if(stringManagerService.checkObjectInString(user.role,post.category.allowView)){
            user.subscribe = stringManagerService.deleteObjectFromString(post,user.subscribe)
            user.save(flush:true)
            println "@" + user.subscribe
            render(template: 'subscribe',model: [postInstance:post])
        }else{
            flash.warning = "You can not view category ("+category.title+")."
            redirect(controller:'home',action:'index')
        }
    }
}
